Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: test transactions can't be saved and reused #1575

Merged
merged 10 commits into from
Sep 20, 2024

Conversation

mmsqe
Copy link
Collaborator

@mmsqe mmsqe commented Sep 13, 2024

Solution:

  • support saving test transactions to files and reuse to speedup local test

👮🏻👮🏻👮🏻 !!!! REFERENCE THE PROBLEM YOUR ARE SOLVING IN THE PR TITLE AND DESCRIBE YOUR SOLUTION HERE !!!! DO NOT FORGET !!!! 👮🏻👮🏻👮🏻

Closes: #1573

nix run .#stateless-testcase generic-gen '{
  "outdir": "/tmp/data",
  "validators": 4,
  "fullnodes": 4,
  "validator_generate_load": true,
  "num_accounts": 8000,
  "num_txs": 1,
  "app_patch": {
      "mempool.max-txs": -1,
      "evm.block-stm-pre-estimate": false
  },
  "config_patch": {
      "mempool.size": 60000
  }
}'

and

stateless-testcase run --num-workers 500 --sleep 0
block 4 701 2024-09-17T01:20:49.614146132Z 534.1916978532505
block 5 7761 2024-09-17T01:20:51.64919105Z 3813.6748818822184
block 6 7761 2024-09-17T01:21:28.398110803Z 211.18988561268972
block 7 7761 2024-09-17T01:21:31.54134243Z 2469.1145928776496
block 8 7761 2024-09-17T01:21:34.476833542Z 2643.850722076818
block 9 7761 2024-09-17T01:21:37.574382043Z 2505.529371771036
block 10 7176 2024-09-17T01:21:40.666338961Z 2320.8609695610157

diable validator_generate_load

nix run .#stateless-testcase generic-gen '{
  "outdir": "/tmp/data",
  "validators": 3,
  "fullnodes": 7,
  "validator_generate_load": false,
  "num_accounts": 12000,
  "num_txs": 1,
  "app_patch": {
      "mempool.max-txs": -1,
      "evm.block-stm-pre-estimate": false
  },
  "config_patch": {
      "mempool.size": 60000
  }
}'

to run

stateless-testcase run --num-workers 10000 --sleep 0
[3208.6092099197745, 3020.13226941868, 2939.3986219935646]
block 11 7761 2024-09-17T04:24:24.579311546Z 2760.620974316728
block 12 7761 2024-09-17T04:24:27.149066255Z 3020.13226941868
block 13 7761 2024-09-17T04:24:29.789402548Z 2939.3986219935646
block 14 7761 2024-09-17T04:24:32.208207883Z 3208.6092099197745
block 15 7761 2024-09-17T04:24:34.869839009Z 2915.880181783207

PR Checklist:

  • Have you read the CONTRIBUTING.md?
  • Does your PR follow the C4 patch requirements?
  • Have you rebased your work on top of the latest master?
  • Have you checked your code compiles? (make)
  • Have you included tests for any non-trivial functionality?
  • Have you checked your code passes the unit tests? (make test)
  • Have you checked your code formatting is correct? (go fmt)
  • Have you checked your basic code style is fine? (golangci-lint run)
  • If you added any dependencies, have you checked they do not contain any known vulnerabilities? (go list -json -m all | nancy sleuth)
  • If your changes affect the client infrastructure, have you run the integration test?
  • If your changes affect public APIs, does your PR follow the C4 evolution of public contracts?
  • If your code changes public APIs, have you incremented the crate version numbers and documented your changes in the CHANGELOG.md?
  • If you are contributing for the first time, please read the agreement in CONTRIBUTING.md now and add a comment to this pull request stating that your PR is in accordance with the Developer's Certificate of Origin.

Thank you for your code, it's appreciated! :)

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Enhanced transaction management and node initialization processes for improved flexibility.
    • Introduced new command-line interface (CLI) commands for transaction generation.
    • Improved configurability of transaction data handling with new parameters.
    • Enhanced transaction handling with asynchronous signing and improved organization of transaction files.
  • Bug Fixes

    • Improved feedback on transaction preparation counts for better user visibility.

@mmsqe mmsqe requested a review from a team as a code owner September 13, 2024 03:03
@mmsqe mmsqe requested review from yihuang and JayT106 and removed request for a team September 13, 2024 03:03
Copy link
Contributor

coderabbitai bot commented Sep 13, 2024

Warning

Rate limit exceeded

@yihuang has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 5 minutes and 38 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Commits

Files that changed from the base of the PR and between 5ea9659 and d99d6fe.

Walkthrough

The changes enhance transaction handling and node initialization within the sendtx.py and stateless.py files. The sendtx.py file introduces asynchronous transaction signing and writing, while stateless.py adds new parameters and CLI commands for generating transactions. Additionally, the transition to a stateless-testcase framework is reflected in the flake.nix and overlay.nix files, indicating a structural rebranding.

Changes

File Path Change Summary
testground/benchmark/benchmark/stateless.py Enhanced transaction management with new parameters and functions for generating transactions. Introduced CLI commands for transaction generation. Modified do_run to load transactions from an output directory.
testground/benchmark/benchmark/sendtx.py Improved transaction handling with asynchronous signing and writing. Refactored prepare_txs for concurrent processing and enhanced error handling.
testground/benchmark/flake.nix Changed default package from pkgs.testground-testcase to pkgs.stateless-testcase, updating configurations accordingly.
testground/benchmark/overlay.nix Renamed exported entities from testground-testcase to stateless-testcase, indicating a shift in architecture.
nix/testground-image.nix Updated Docker image configuration to replace testground-testcase with stateless-testcase.

Assessment against linked issues

Objective Addressed Explanation
Generate all test accounts and transactions in the gen phase. (#1573)

Possibly related PRs

Poem

🐰 In the realm of code, where transactions play,
New features emerge, brightening the day.
With each hop and tweak, our benchmarks refine,
A stateless adventure, where all will align.
So gather your data, let the metrics unfold,
In this world of testing, new stories are told! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Sep 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 15.24%. Comparing base (3c8be96) to head (d99d6fe).
Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1575   +/-   ##
=======================================
  Coverage   15.24%   15.24%           
=======================================
  Files          67       67           
  Lines        4874     4874           
=======================================
  Hits          743      743           
  Misses       4037     4037           
  Partials       94       94           

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 753782d and 3473b73.

Files selected for processing (1)
  • testground/benchmark/benchmark/stateless.py (2 hunks)

testground/benchmark/benchmark/stateless.py Outdated Show resolved Hide resolved
testground/benchmark/benchmark/stateless.py Outdated Show resolved Hide resolved
testground/benchmark/benchmark/stateless.py Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 356ab72 and 03fba81.

Files selected for processing (1)
  • testground/benchmark/benchmark/stateless.py (3 hunks)
Additional comments not posted (1)
testground/benchmark/benchmark/stateless.py (1)

363-363: LGTM!

The usage of calculate_tps function in the dump_block_stats function is correct. The calculate_tps function is already calculating the average TPS for a range of blocks as suggested in the past review comment.

testground/benchmark/benchmark/stateless.py Outdated Show resolved Hide resolved
testground/benchmark/benchmark/stateless.py Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
testground/benchmark/benchmark/stateless.py (1)

355-370: LGTM!

The function is using the calculate_tps function as suggested in the past review comment.

Consider adding more statistics such as average TPS and median TPS.

The function can be further improved by adding more statistics such as average TPS and median TPS as suggested in the past review comment.

Apply this diff to add more statistics:

     top_tps = sorted(tps_list, reverse=True)[:3]
     print("top_tps", top_tps)
+    print("average_tps", sum(tps_list) / len(tps_list))
+    print("median_tps", sorted(tps_list)[len(tps_list) // 2])
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 03fba81 and a06f1a9.

Files selected for processing (1)
  • testground/benchmark/benchmark/stateless.py (3 hunks)
Additional comments not posted (3)
testground/benchmark/benchmark/stateless.py (3)

316-326: The past review comment is still valid and applicable:

coderabbitai[bot]: Consider simplifying the function using the datetime module.

The function can be simplified by using the datetime module to parse and format the timestamp.

Apply this diff to refactor the function:

-def truncate_fractional_seconds(timestamp):
-    (
-        date_time_part,
-        _,
-        _,
-    ) = timestamp.partition("Z")
-    if "." in date_time_part:
-        date_time_part, fractional_part = date_time_part.split(".")
-        fractional_part = fractional_part[:6]
-        return f"{date_time_part}.{fractional_part}Z"
-    return timestamp
+from datetime import datetime
+
+def truncate_fractional_seconds(timestamp):
+    dt = datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%fZ")
+    return dt.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

329-354: The past review comment is still valid and applicable:

coderabbitai[bot]: LGTM!

The function logic is correct and it handles the case where there is no valid time difference.

Consider optimizing the function by caching the previous block's timestamp.

The function can be optimized by caching the previous block's timestamp to avoid redundant API calls.

Apply this diff to optimize the function:

+prev_timestamp = None
+
 def calculate_tps(start_height, end_height):
     total_txs = 0
     total_time = 0
 
     for height in range(start_height + 1, end_height):
         blk = block(height)
         timestamp = blk["result"]["block"]["header"]["time"]
-        prev_blk = block(height - 1)
-        txs = len(prev_blk["result"]["block"]["data"]["txs"])
+        if prev_timestamp is None:
+            prev_blk = block(height - 1)
+            prev_timestamp = prev_blk["result"]["block"]["header"]["time"]
+        txs = len(blk["result"]["block"]["data"]["txs"])
         if txs > 0:
-            prev_timestamp = prev_blk["result"]["block"]["header"]["time"]
             time_format = "%Y-%m-%dT%H:%M:%S.%fZ"
             current_time, previous_time = (
                 datetime.strptime(truncate_fractional_seconds(ts), time_format)
                 for ts in (timestamp, prev_timestamp)
             )
             diff = (current_time - previous_time).total_seconds()
             total_time += diff
             total_txs += txs
+            prev_timestamp = timestamp
 
     if total_time > 0:
         average_tps = total_txs / total_time
         return average_tps
     else:
         return 0

49-50: LGTM!

The function is correctly parsing the options argument as JSON if it is a string.

@mmsqe mmsqe marked this pull request as draft September 14, 2024 13:29
@mmsqe mmsqe changed the title Problem: no top tps log in testground Problem: load generator is slow Sep 16, 2024
@mmsqe mmsqe force-pushed the top_tps branch 2 times, most recently from 394e3f0 to 4f7a658 Compare September 16, 2024 08:52
yihuang added a commit to yihuang/cronos that referenced this pull request Sep 16, 2024
Solution:
- extract standalone changes from crypto-org-chain#1575
- use a simple and deterministic way to generate test accounts
github-merge-queue bot pushed a commit that referenced this pull request Sep 16, 2024
* Problem: bulk-add-genesis-account is not used in testground

Solution:
- extract standalone changes from #1575
- use a simple and deterministic way to generate test accounts

* fix

* fix

* fix coins

* fix comment

* multi coins

* cleanup

* fix py lint

---------

Co-authored-by: mmsqe <[email protected]>
@mmsqe mmsqe marked this pull request as ready for review September 17, 2024 01:28
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a699f19 and 65cf863.

Files selected for processing (2)
  • testground/benchmark/benchmark/sendtx.py (1 hunks)
  • testground/benchmark/benchmark/stateless.py (9 hunks)
Files skipped from review as they are similar to previous changes (1)
  • testground/benchmark/benchmark/stateless.py
Additional context used
GitHub Check: Lint python
testground/benchmark/benchmark/sendtx.py

[failure] 65-65:
./testground/benchmark/benchmark/sendtx.py:65:1: BLK100 Black would make changes.


[failure] 65-65:
./testground/benchmark/benchmark/sendtx.py:65:1: W293 blank line contains whitespace


[failure] 76-76:
./testground/benchmark/benchmark/sendtx.py:76:89: E501 line too long (92 > 88 characters)

Additional comments not posted (3)
testground/benchmark/benchmark/sendtx.py (3)

15-17: LGTM!

The sendtx function has been simplified to handle a single transaction, which improves readability and maintainability. The logic is correct, and the implementation is accurate.


20-40: LGTM!

The generate_load function has been modified to read transactions from a file, which allows for more flexible load testing scenarios. The use of a ThreadPoolExecutor enables concurrent transaction sending, improving performance. The logic is correct, and the implementation is accurate.


43-50: LGTM!

The create_txs function encapsulates the logic for creating transactions, which improves code modularity and reusability. The function generates a list of raw transaction hex strings for a given account, which can be used for efficient load testing. The logic is correct, and the implementation is accurate.

testground/benchmark/benchmark/sendtx.py Outdated Show resolved Hide resolved
testground/benchmark/benchmark/sendtx.py Outdated Show resolved Hide resolved
yihuang added a commit to yihuang/cronos that referenced this pull request Sep 18, 2024
yihuang added a commit to yihuang/cronos that referenced this pull request Sep 18, 2024
github-merge-queue bot pushed a commit that referenced this pull request Sep 18, 2024
* Problem: testground block stats don't calculate tps directly

Solution:
- add tps calculation, extract from #1575

* cleanup

* Update testground/benchmark/benchmark/stats.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: yihuang <[email protected]>

* skip block 1

---------

Signed-off-by: yihuang <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: mmsqe <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 09f8fe3 and 77ad17c.

Files selected for processing (1)
  • testground/benchmark/benchmark/stateless.py (8 hunks)
Additional context used
Ruff
testground/benchmark/benchmark/stateless.py

9-9: datetime.datetime imported but unused

Remove unused import: datetime.datetime

(F401)

GitHub Check: Lint python
testground/benchmark/benchmark/stateless.py

[failure] 9-9:
./testground/benchmark/benchmark/stateless.py:9:1: F401 'datetime.datetime' imported but unused

Additional comments not posted (6)
testground/benchmark/benchmark/stateless.py (6)

26-26: LGTM!

The import statement is correct and the imported functions are used in the code.


109-117: LGTM!

The additional arguments passed to the init_node_local function are correct and used to configure the node initialization process.


126-126: LGTM!

The num_accounts and num_txs arguments passed to the init_node_local function for fullnodes are correct and used to configure the fullnode initialization process.


189-197: LGTM!

The num_workers and sleep options added to the run function are correct and used to configure the load generation process. The default values are appropriate.


Line range hint 212-256: LGTM!

The code changes in the run function are correct:

  • The do_run function is called with the num_workers and sleep arguments to configure the load generation process.
  • The output data collection and saving process is correct and only applies to validator nodes.
  • The generate_load function is called with the num_workers and sleep arguments to generate load.

344-360: LGTM!

The code changes in the init_node_local function are correct:

  • The num_txs and validator_generate_load parameters are added to configure the transaction generation process during node initialization.
  • The gen_txs function is called with the correct arguments to generate transactions.
  • The transaction generation is conditionally executed based on the validator_generate_load flag.

testground/benchmark/benchmark/stateless.py Outdated Show resolved Hide resolved
flake.nix Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range and nitpick comments (3)
testground/benchmark/benchmark/sendtx.py (3)

28-32: Consider renaming the function to write_tx.

The function name async_write_tx suggests that it is intended to be used asynchronously, but there are no async/await keywords used within the function. To avoid confusion, consider renaming the function to write_tx since it doesn't contain any asynchronous operations.

-def async_write_tx(account, tx, file_path):
+def write_tx(account, tx, file_path):
     raw_tx = account.sign_transaction(tx).rawTransaction
     with open(file_path, "w") as file:
         file.write(ujson.dumps([raw_tx.hex()]))

34-37: Fix the typo in the function name.

There is a typo in the function name get_txs_foler. It should be get_txs_folder for clarity and consistency.

-def get_txs_foler(outdir: Path, global_seq):
+def get_txs_folder(outdir: Path, global_seq):
     folder = outdir / TMP_TXS_FOLDER / str(global_seq)
     folder.mkdir(parents=True, exist_ok=True)
     return folder

59-65: Update the function name based on the previous suggestion.

Update the function name get_txs_foler to get_txs_folder based on the previous suggestion to fix the typo.

 def read_txs(outdir: Path, global_seq):
     txs = []
-    folder = get_txs_foler(outdir, global_seq)
+    folder = get_txs_folder(outdir, global_seq)
     for file in folder.glob("*.json"):
         with open(file, "r") as f:
             tx_data = ujson.load(f)
             txs.append(tx_data[0])
     return txs
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0100ffd and 5ea9659.

Files selected for processing (2)
  • testground/benchmark/benchmark/sendtx.py (3 hunks)
  • testground/benchmark/benchmark/stateless.py (7 hunks)
Files skipped from review as they are similar to previous changes (1)
  • testground/benchmark/benchmark/stateless.py
Additional comments not posted (5)
testground/benchmark/benchmark/sendtx.py (5)

3-3: LGTM!

The import statement for the Path class from the pathlib module is correctly placed at the top of the file. The Path class is a useful utility for working with file paths in a cross-platform manner.


8-8: LGTM!

The import statement for the gen_account function from the .utils module is correctly placed at the top of the file. The gen_account function is likely used to generate test accounts for transaction preparation.


14-14: LGTM!

The constant TMP_TXS_FOLDER is defined correctly, following the naming convention for constants in Python. It specifies the folder name for storing temporary transaction files.


85-85: LGTM!

Creating an aiohttp.TCPConnector with a connection limit specified by the CONNECTION_POOL_SIZE constant is a good practice. It helps control the maximum number of concurrent connections to the server and provides a centralized configuration option.


Line range hint 1-90: Overall assessment of the file:

The file follows a modular and asynchronous approach for preparing, reading, and sending transactions, which is a good design choice. The separation of concerns into different functions improves code organization and reusability. The use of aiohttp and asyncio for asynchronous processing enables concurrent handling of transactions, leading to better performance.

The file also utilizes constants for configuration values such as GAS_PRICE, CHAIN_ID, LOCAL_JSON_RPC, and CONNECTION_POOL_SIZE, making it easier to modify and maintain these values in a centralized manner.

However, there are a couple of areas that could be improved:

  1. The error handling in the prepare_txs function could be enhanced by logging errors with more details or retrying the signing process in case of transient failures. This would provide better visibility into any issues encountered during transaction preparation.

  2. The typo in the function name get_txs_foler should be fixed to get_txs_folder for clarity and consistency with the intended functionality.

Overall, the file demonstrates a solid structure and design, with room for minor improvements in error

testground/benchmark/benchmark/sendtx.py Outdated Show resolved Hide resolved
yihuang and others added 2 commits September 20, 2024 15:02
Solution:
- support saving test transactions to files and reuse to speedup local test

Co-authored-by: mmsqe <[email protected]>
@yihuang yihuang changed the title Problem: load generator is slow Problem: test transactions can't be saved and reused Sep 20, 2024
@yihuang
Copy link
Collaborator

yihuang commented Sep 20, 2024

diff --git a/testground/benchmark/benchmark/stateless.py b/testground/benchmark/benchmark/stateless.py
index 5e4db258..4fb54d0e 100644
--- a/testground/benchmark/benchmark/stateless.py
+++ b/testground/benchmark/benchmark/stateless.py
@@ -6,6 +6,7 @@ import socket
 import subprocess
 import tarfile
 import tempfile
+import threading
 import time
 from pathlib import Path
 from typing import List
@@ -220,12 +221,26 @@ def _gen_txs(
     num_txs: int = 1000,
 ):
     outdir = Path(outdir)
-    for global_seq in range(nodes):
+
+    # create dir in advance to avoid conflict in parallel task
+    (outdir / transaction.TXS_DIR).mkdir(parents=True, exist_ok=True)
+
+    def job(global_seq: int):
         print("generating", num_accounts * num_txs, "txs for node", global_seq)
         txs = transaction.gen(global_seq, num_accounts, num_txs)
         transaction.save(txs, outdir, global_seq)
         print("saved", len(txs), "txs for node", global_seq)

+    threads = [
+        threading.Thread(target=job, args=(global_seq,)) for global_seq in range(nodes)
+    ]
+
+    for t in threads:
+        t.start()
+
+    for t in threads:
+        t.join()
+

 def do_run(
     datadir: Path, home: Path, cronosd: str, group: str, global_seq: int, cfg: dict

I actually tested this parallel implementation, CPU usage never pass 100%, and there's zero speedup, even several seconds slower, the reason is eth-account rely on pure python cryptographic implementation, so it's all protected by GIL. @mmsqe

@mmsqe
Copy link
Collaborator Author

mmsqe commented Sep 20, 2024

yes, I thought need generate tx_{acc_i}_{tx_i}.json file in parallel avoid regenerate when changing num_accts and num_txs

@yihuang
Copy link
Collaborator

yihuang commented Sep 20, 2024

yes, I thought need generate tx_{acc_i}_{tx_i}.json file one by one avoid regenerate when changing different configs

I think we just backup the whole txs directory to reuse it.
When num_accounts changed, just generate new ones, it's not that slow to generate actually.

@yihuang yihuang added this pull request to the merge queue Sep 20, 2024
Merged via the queue into crypto-org-chain:main with commit 670fd8d Sep 20, 2024
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problem: load generator might be the bottleneck in benchmark
2 participants